package com.ruoyi.common.utils.modbus;

import com.ghgande.j2mod.modbus.facade.ModbusTCPMaster;
import com.ghgande.j2mod.modbus.procimg.InputRegister;
import com.ghgande.j2mod.modbus.procimg.Register;
import com.ghgande.j2mod.modbus.util.BitVector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.HashMap;
import java.util.Map;

/**
 * modbus 读取数据
 **/
public class J2modUtils {
    static Log log = LogFactory.getLog(J2modUtils.class);

    public static void main(String[] args) throws Exception {
        // 定义Modbus TCP主机的IP地址和端口
        String host = "192.168.1.88";
        int port = 11001;
//        String host = "192.168.0.91";
//        int port = 11004;

        // 设定从站ID
        int slaveId = 1;
        // 起始地址，从0开始即为第1个寄存器
        int startAddress = 261;
        // 读取的寄存器数量，从第1个寄存器开始读取9个寄存器
        int registerQuantity = 279-261 + 1;
        //01
//        Map<Integer, Boolean> map1 = readCoils(host, port, slaveId, startAddress, registerQuantity);
//        System.out.println("01指令，host:" + host + ",port:" + port + ",结果：" + map1);
        //02
//        Map<Integer, Boolean> map2 = readInputDiscretes(host, port, slaveId, startAddress, registerQuantity);
//        System.out.println("02指令，host:" + host + ",port:" + port + ",结果：" + map2);
        //03
        Map<Integer, Register> map3 = readMultipleRegisters(host, port, slaveId, startAddress, registerQuantity);
        System.out.println("03指令，host:" + host + ",port:" + port + ",结果：" + map3);
        //04
//        Map<Integer, InputRegister> map4 = readInputRegisters(host, port, slaveId, startAddress, registerQuantity);
//        System.out.println("04指令，host:" + host + ",port:" + port + ",结果：" + map4);

//        for (int i = 0; i < 1000; i++) {
////            Thread.sleep(1000);
//            Map<Integer, Integer> map1 = readMultipleRegisters(host, port, slaveId, startAddress, registerQuantity);
//            System.out.println(map1);
//        }


    }

    /**
     * 01指令批量读取
     *
     * @param host             ip地址
     * @param port             端口
     * @param slaveId          从站ID
     * @param startAddress     起始地址，从0开始即为第1个寄存器
     * @param registerQuantity 读取的寄存器数量，从第1个寄存器开始读取9个寄存器
     * @return 设备数据
     */
    public static Map<Integer, Boolean> readCoils(String host, int port, int slaveId, int startAddress, int registerQuantity) {
        long starTime = System.currentTimeMillis();
        Map<Integer, Boolean> map = new HashMap<>();
        // 创建Modbus TCP主机实例
        ModbusTCPMaster master = new ModbusTCPMaster(host, port);
        master.setTimeout(1000);
        try {
            // 打开连接
            master.connect();
//            Thread.sleep(100);

            // 执行批量读取操作
            BitVector bitVector = master.readCoils(slaveId, startAddress, registerQuantity);
            // 输出读取的寄存器值
            for (int i = 0; i < bitVector.size(); i++) {
                map.put((startAddress + i), bitVector.getBit(i));
                log.info("01 Register " + (startAddress + i) + " Value: " + bitVector.getBit(i));
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            // 关闭连接
            if (master.isConnected()) {
                master.disconnect();
            }
        }
        long endTime = System.currentTimeMillis();
        log.info("01 结束时间" + (endTime - starTime));
        return map;
    }


    /**
     * 02指令批量读取
     *
     * @param host             ip地址
     * @param port             端口
     * @param slaveId          从站ID
     * @param startAddress     起始地址，从0开始即为第1个寄存器
     * @param registerQuantity 读取的寄存器数量，从第1个寄存器开始读取9个寄存器
     * @return 设备数据
     */
    public static Map<Integer, Boolean> readInputDiscretes(String host, int port, int slaveId, int startAddress, int registerQuantity) throws Exception {
        Map<Integer, Boolean> map = new HashMap<>();
        // 创建Modbus TCP主机实例
        ModbusTCPMaster master = new ModbusTCPMaster(host, port);
        master.setTimeout(200);
        // 打开连接
        master.connect();
        // 执行批量读取操作
        BitVector bitVector = master.readInputDiscretes(slaveId, startAddress, registerQuantity);
        // 输出读取的寄存器值
        for (int i = 0; i < bitVector.size(); i++) {
            map.put((startAddress + i), bitVector.getBit(i));
        }
        return map;
    }

    /**
     * 03指令批量读取
     *
     * @param host             ip地址
     * @param port             端口
     * @param slaveId          从站ID
     * @param startAddress     起始地址，从0开始即为第1个寄存器
     * @param registerQuantity 读取的寄存器数量，从第1个寄存器开始读取9个寄存器
     * @return 设备数据
     */
    public static Map<Integer, Register> readMultipleRegisters(String host, int port, int slaveId, int startAddress, int registerQuantity) throws Exception {
        Map<Integer, Register> map = new HashMap<>();
        // 创建Modbus TCP主机实例
        ModbusTCPMaster master = new ModbusTCPMaster(host, port);
        master.setTimeout(200);
        // 打开连接
        master.connect();
        // 执行批量读取操作
        Register[] registers = master.readMultipleRegisters(slaveId, startAddress, registerQuantity);
        // 输出读取的寄存器值
        for (int i = 0; i < registers.length; i++) {
            map.put((startAddress + i), registers[i]);
        }
        return map;
    }


    /**
     * 04指令批量读取
     *
     * @param host             ip地址
     * @param port             端口
     * @param slaveId          从站ID
     * @param startAddress     起始地址，从0开始即为第1个寄存器
     * @param registerQuantity 读取的寄存器数量，从第1个寄存器开始读取9个寄存器
     * @return 设备数据
     */
    public static Map<Integer, InputRegister> readInputRegisters(String host, int port, int slaveId, int startAddress, int registerQuantity) {
        long starTime = System.currentTimeMillis();
        Map<Integer, InputRegister> map = new HashMap<>();
        // 创建Modbus TCP主机实例
        ModbusTCPMaster master = new ModbusTCPMaster(host, port);
        master.setTimeout(1000);
        try {
            // 打开连接
            master.connect();
            Thread.sleep(100);
            // 执行批量读取操作
            InputRegister[] inputRegisters = master.readInputRegisters(slaveId, startAddress, registerQuantity);
            // 输出读取的寄存器值
            for (int i = 0; i < inputRegisters.length; i++) {
                map.put((startAddress + i), inputRegisters[i]);
                log.info("04 Register " + (startAddress + i) + " Value: " + inputRegisters[i].toShort());
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            // 关闭连接
            if (master.isConnected()) {
                master.disconnect();
            }
        }
        long endTime = System.currentTimeMillis();
        log.info("04 结束时间" + (endTime - starTime));
        return map;
    }

}
